package multiIntro;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import polyglot.ast.Block;
import polyglot.ast.Eval;
import polyglot.ast.Expr;
import polyglot.ast.Node;
import polyglot.ast.NodeFactory;
import polyglot.ext.jl.ast.Node_c;
import polyglot.types.TypeSystem;
import polyglot.util.Position;
import polyglot.visit.NodeVisitor;
import xaj.xc.ast.NodeXAJ;

//importsymbol multiIntro.MethodInvocationEval;

//Versão que deve ser compilada/gerado automaticamente
//para a classe sintática Eval
public class BlockEval extends Node_c implements NodeXAJ, xaj.lang.Map {
	/*@grammar using MethodInvocationEval {
		BlockEval -> b = block;
	}*/
	
	private Map map;
	
	public BlockEval(Position pos) {
		super(pos);
		this.map = new HashMap();
		System.out.println("Criou um objeto BlockEval");
	}
	
	public Object get(String name) {
		return map.get(name);
	}

	public boolean add(String name, Object value) {
		if(!map.containsKey(name)) {
			map.put(name, value);
			return true;
		} else
			return false;
	}

	public Iterator iterator() {
		return map.keySet().iterator();
	}

	public void set(String name, Object value) {
		if(map.containsKey(name)) {
			map.keySet();
			map.put(name, value);
		}
	}
	
	//Deve ser implementado para visitar os filhos de block
	/*public Node visitChildren(NodeVisitor v) {
		//Acho que esse código pode ser gerado automaticamente e
		//suponho que seja genérico e funciona para todos os casos
		Iterator it = iterator();
		while(it.hasNext()) {
			String name = (String) it.next();
			Object ob = get(name);
			if(ob instanceof Node) {
				set(name, ((Node) ob).visit(v));
			}				
		}
		return this;
	}*/
	
	public Node desugar(NodeFactory ft, TypeSystem ts) {		
		Block b = (Block) get("b");
		Block newblock = ft.Block(position());
		for(Object ob : b.statements()) {
			polyglot.ast.Stmt stmt = (polyglot.ast.Stmt) ob;
			if(stmt instanceof polyglot.ast.Eval) {
				polyglot.ast.Eval eval = (Eval) stmt;
				if(eval.expr() instanceof NodeXAJ) {
					Expr expr = eval.expr();
					polyglot.ast.Eval newEval = ft.Eval(eval.position(),
							(Expr) ((NodeXAJ) expr).desugar(ft, ts));
					stmt = newEval;
				}
			}
			newblock = newblock.append(stmt);
		}
		return newblock;
	}
}
